Skip to main content

Basic Syntax

Every Rust program has at least one function: main.

fn main() {
println!("Hello, Rust!");
}
PartMeaning
fnKeyword to define a function
mainEntry point of the program
{}Function body
println!Macro to print output
;Ends a statement

Statements vs Expressions

Rust is expression-based, unlike C or Java.

  • Statement does something but returns no value (let x = 5;).
  • Expression evaluates to a value (5 + 3)
let y = {
let x = 3;
x + 1 // no semicolon → expression
};

y becomes 4

Variables and Mutability

In Rust, variables are created using the let keyword.

let x = 10;
// x = 20; ❌ error

Rust variables are immutable by default (safety feature).

Why Rust Does This

  • Prevent accidental changes
  • Improve safety
  • Make code easier to reason about
  • Enable compiler optimizations

If something must change, you must say it explicitly.

Mutable Variables

To allow a variable to change, use mut.

let mut x = 10;
x = 20; // ✅ allowed
KeywordMeaning
letDeclare variable
mutMake variable mutable

Mutability and References (Preview)

let mut x = 10;
let y = &x;

// x = 20; ❌ cannot modify while borrowed

Rust prevents data races at compile time
This becomes important in ownership & borrowing

Data Types (Basics)

Rust is statically typed, but usually infers types.

Rust Data Types Categories

Rust has two main categories of data types:

CategoryDescription
ScalarHolds a single value
CompoundHolds multiple values

Scalar Data Types

Scalar types represent a single value.

Rust has four scalar types:

  1. Integers
  2. Floating-point numbers
  3. Booleans
  4. Characters

Integer Types

Integers are whole numbers (no decimals).

TypeMeaning
iSigned (positive + negative)
uUnsigned (only positive)
let a: i32 = 10;
let b = 20; // inferred as i32
  • i32 → signed integer
  • u32 → unsigned integer
  • f64 → floating point
  • bool → true / false
  • char → single Unicode character

Floating Point Types

Floating-point numbers represent decimals.

TypeSize
f3232-bit
f6464-bit (default)

Character Type (char)

Rust char:

  • Uses single quotes
  • Represents a Unicode scalar value
  • Is 4 bytes (not 1 byte)
let x: i32 = 42;
let pi: f64 = 3.14;
let is_rust_fun: bool = true;
let letter: char = 'R';

Rust supports Unicode by default

Compound Data Types

Compound types group multiple values into one type.

Rust has two primitive compound types:

  1. Tuples
  2. Arrays

Tuples

  • Hold multiple values (let person = ("Alice", 25, true);)
  • Have different types
  • Have a fixed size

Tuple Destructuring: let (name, age, active) = person;
Accessing Tuple Values: let name = person.0;

Arrays

  • Store multiple values of same type
  • Have fixed length
  • Stored in stack memory
let scores: [i32; 3] = [80, 90, 100];
[i32; 3]Meaning
i32Type of elements
3Number of elements

A slice is a reference to part of a collection.

let arr = [10, 20, 30, 40];
let slice = &arr[1..3];

s contains: [20, 30] Arrays vs Tuples

FeatureTupleArray
TypesDifferent allowedSame only
SizeFixedFixed
Access.0, .1[index]
Use caseGroup related valuesLists of data

Constants

  • Are always immutable
  • Must have a type
  • Use SCREAMING_SNAKE_CASE
const MAX_USERS: u32 = 100;

Static Variables (Brief Intro)

static LANGUAGE: &str = "Rust";
  • Stored in a fixed memory location
  • Rarely used by beginners
  • Different from const

Shadowing (Rust-Specific Feature)

Rust allows re-declaring variables with the same name.

let x = 5;
let x = x + 1;
let x = x * 2;

println!("{}", x); // 12

Shadowing ≠ mutability
Creates a new variable

Mutability changes a value
Shadowing creates a new variable

Why Shadowing Is Useful

Example: Type Change

let spaces = "   ";
let spaces = spaces.len();

Why mut Can’t Do This

let mut spaces = "   ";
spaces = spaces.len(); // ❌ type mismatch

Shadowing allows type transformation
mut does not

Control Flow: if, else

let number = 7;

if number > 5 {
println!("Greater than 5");
} else {
println!("5 or less");
}

if as Expression

let result = if number > 5 { 10 } else { 0 };

Both branches must return same type

match

match compares a value against patterns and executes the matching branch.

Think of it as: switch on steroids

let day = 3;

match day {
1 => println!("Monday"),
2 => println!("Tuesday"),
3 => println!("Wednesday"),
_ => println!("Invalid day"),
}
PartMeaning
=>Pattern match arrow
_Catch-all pattern

match is also an expression.

let number = 5;

let result = match number {
0 => "Zero",
1 => "One",
_ => "Many",
};

Pattern Matching with Ranges

let score = 78;

match score {
90..=100 => "A",
80..=89 => "B",
70..=79 => "C",
_ => "F",
};

Matching Enums (Very Common)

enum Direction {
North,
South,
East,
West,
}

let dir = Direction::North;

match dir {
Direction::North => println!("Up"),
Direction::South => println!("Down"),
Direction::East => println!("Right"),
Direction::West => println!("Left"),
}

if let (Shortcut for match)

let value = Some(5);

if let Some(x) = value {
println!("Value is {}", x);
}

Cleaner when you only care about one pattern

Loops

loop (infinite loop)

let mut count = 0;

let result = loop {
count += 1;
if count == 5 {
break count * 2;
}
};

loop can return values using break.

while

let mut n = 3;

while n > 0 {
println!("{}", n);
n -= 1;
}

for (most common)

for i in 1..=5 {
println!("{}", i);
}
SyntaxMeaning
1..51 to 4
1..=51 to 5

Comments

  • Single-line // This is a comment
  • Multi-line
/*
Multi-line comment
*/

Basic Collections

Tuple (fixed size, mixed types)

let person = ("Alice", 30, true);
println!("{}", person.0);

Array (fixed size, same type)

let numbers = [1, 2, 3, 4];
println!("{}", numbers[0]);

Strings (Very Important)

String Literal (&str)

let name = "Rust";

String (heap allocated, growable)

let mut name = String::from("Rust");
name.push_str(" Language");

Basic Ownership Preview (Light Intro)

let s1 = String::from("hello");
let s2 = s1;
// println!("{}", s1); ❌ error

Ownership moved from s1s2

Full Example Program

fn main() {
let mut score = 50;

score += 10;

if score >= 60 {
println!("Pass");
} else {
println!("Fail");
}

for i in 1..=3 {
println!("Attempt {}", i);
}
}

What This Demonstrates

  • Variables & mutability
  • if expressions
  • for loop
  • Printing output